#include "StdAfx.h"
#include "ModelEditor.h"
#include "EditorHelper.h"
#include "DocUndo.h"
#include "AnyDocument.h"
#include <memory>
CModelEditor::CModelEditor(void):
m_pEditorCur(NULL)
{

}

CModelEditor::~CModelEditor(void)
{
	Destroy();
}
void CModelEditor::Destroy()
{
	if(m_pEditorCur)
		m_pEditorCur->Finish();

	std::deque<CEditorHelper*>::iterator it = m_EditorPtrs.begin();
	for(; it != m_EditorPtrs.end(); ++it)
	{
		delete *it;
		*it = NULL;
	}

	m_EditorPtrs.clear();

	m_pEditorCur = NULL;
}
TDF_Label CModelEditor::NewLabel(const TCollection_ExtendedString& szName)
{
	TDF_Label label = TDF_TagSource::NewChild(GetRootLabel());
	TDataStd_Name::Set(label, szName);

	return label;
}

void CModelEditor::AddSubEditor(CEditorHelper* pEditor, UINT nStep)
{
	pEditor->SetStep(nStep);
	m_EditorPtrs.push_back(pEditor);
}

void CModelEditor::Initialize(CAnyView* pView)
{
	CAnyEditor::Initialize(pView);

	m_bStart = false;

	if(m_EditorPtrs.size() < 1)
	{
		m_pEditorCur = NULL;
	}
	else
	{
		m_pEditorCur = m_EditorPtrs.front();
		std::deque<CEditorHelper*>::iterator it = m_EditorPtrs.begin();
		for(; it != m_EditorPtrs.end(); ++it)
		{
			(*it)->Initialize(pView);
		}

		m_pEditorCur->Start();
	}
}

EditorState CModelEditor::OnLButtonDown(UINT nFlags, long x, long y)
{
	if(m_pEditorCur == NULL)
		return ES_FINISHED;

	m_bStart = true;
	EditorState es = ES_CONTINUE;
	if(m_pEditorCur->OnLButtonDown(nFlags, x, y) == ES_FINISHED)
	{
		m_pEditorCur->Finish();
		delete m_pEditorCur;
		m_pEditorCur = NULL;

		m_EditorPtrs.pop_front();
		if(!m_EditorPtrs.empty()) // next
		{
			m_pEditorCur = m_EditorPtrs.front();
			m_pEditorCur->Start();
			m_pEditorCur->OnLButtonDown(nFlags, x, y);
		}
		else
		{
			Finish();

			Initialize(m_pView);

			//es = ES_FINISHED;
		}

	}
	return es;
}
EditorState CModelEditor::OnLButtonUp(UINT nFlags, long x, long y)
{
	if(m_pEditorCur)
		m_pEditorCur->OnLButtonUp(nFlags, x, y);

	return ES_CONTINUE;
}
void CModelEditor::OnMouseMove(UINT nFlags, long x, long y)
{
	if(m_pEditorCur)
	{
		m_pEditorCur->OnMouseMove(nFlags, x, y);
		//if(m_bStart)
		Preview();

	}
}

void CModelEditor::Preview()
{
	// before preview
	GetRender()->Remove(m_ShapeRep, false);

	if(CreatePreviewShape())
	{
		// display
		m_ShapeRep.SetColor(Quantity_NOC_RED);
		m_ShapeRep.SetTransparency(0.5);
		GetRender()->Render(m_ShapeRep, false);
		GetRender()->Hilight(m_ShapeRep, true);
	}

	if(m_pEditorViewer)
		m_pEditorViewer->OnParamChanged(CurrentStep());
}
void CModelEditor::Finish()
{
	// remove temporay shape
	GetRender()->Remove(m_ShapeRep, false);

	CAnyDocument* pADoc = GetView()->GetDocument();
	std::auto_ptr<CDocUndo> pDocUndo(new CDocUndo(pADoc));

	TDF_Label label;
	if(!CreateShapeLabel(label))
	{
		pDocUndo->Abort();
		return;
	}

	// add it to the document
	if(!OnAddShape(label, pADoc))
	{
		pDocUndo->Abort();
		return;
	}

	// display it in view
	Handle(TPrsStd_AISPresentation) prs= TPrsStd_AISPresentation::Set(label, TNaming_NamedShape::GetID()); 
	prs->SetColor(Quantity_NOC_BLACK);
	prs->Display(Standard_True);
	// Attach an integer attribute to L to memorize it's displayed
	TDataStd_Integer::Set(label, 1);
	GetRender()->UpdateCurrentViewer();

	pDocUndo->Commit();
	pADoc->GetUndoMgr()->Add(pDocUndo.release());
}

bool CModelEditor::OnAddShape(TDF_Label& shapeLabel,CAnyDocument* pADoc)
{
	return pADoc->AddShape(shapeLabel, GetData());
}

void CModelEditor::SetPreviewShape(const TopoDS_Shape& shape)
{
	m_ShapeRep = CShapeReps(shape);
}

void CModelEditor::Abort()
{
	Destroy();
	GetRender()->Remove(m_ShapeRep, true);
	Initialize(GetView());
}

int CModelEditor::CurrentStep()
{
	if(m_pEditorCur)
	{
		return m_pEditorCur->GetStep();
	}

	return -1;
}